package com.youlai.boot.common.util;

import cn.idev.excel.EasyExcel;
import cn.idev.excel.event.AnalysisEventListener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * Excel 工具类
 *
 * @author Jason
 * @since 2025/05/13
 */
@Slf4j
public class ExcelUtils {

    /**
     * 导入Excel
     *
     * @param is Excel输入流
     * @param clazz 实体类
     * @param listener 解析监听器
     * @param <T> 泛型
     */
    public static <T> void importExcel(InputStream is, Class clazz, AnalysisEventListener<T> listener) {
        EasyExcel.read(is, clazz, listener).sheet().doRead();
    }
    
    /**
     * 导入Excel
     *
     * @param file Excel文件
     * @param clazz 实体类
     * @param <T> 泛型
     * @return 数据列表
     */
    public static <T> List<T> importExcel(MultipartFile file, Class<T> clazz) {
        try {
            return EasyExcel.read(file.getInputStream())
                    .head(clazz)
                    .sheet()
                    .doReadSync();
        } catch (IOException e) {
            log.error("Excel导入失败", e);
            throw new RuntimeException("Excel导入失败: " + e.getMessage());
        }
    }
    
    /**
     * 导出Excel
     *
     * @param response HTTP响应对象
     * @param dataList 数据列表
     * @param clazz 实体类
     * @param fileName 文件名
     * @param sheetName 表单名
     * @param <T> 泛型
     */
    public static <T> void exportExcel(HttpServletResponse response, List<T> dataList, Class<T> clazz, 
                                       String fileName, String sheetName) {
        try {
            setExcelResponseHeader(response, fileName);
            EasyExcel.write(response.getOutputStream(), clazz)
                    .sheet(sheetName)
                    .doWrite(dataList);
        } catch (IOException e) {
            log.error("Excel导出失败", e);
            throw new RuntimeException("Excel导出失败: " + e.getMessage());
        }
    }
    
    /**
     * 导出Excel
     *
     * @param response HTTP响应对象
     * @param dataList 数据列表
     * @param clazz 实体类
     * @param fileName 文件名
     * @param <T> 泛型
     */
    public static <T> void exportExcel(HttpServletResponse response, List<T> dataList, Class<T> clazz, 
                                       String fileName) {
        exportExcel(response, dataList, clazz, fileName, "Sheet1");
    }
    
    /**
     * 设置Excel响应头
     *
     * @param response HTTP响应对象
     * @param fileName 文件名
     */
    private static void setExcelResponseHeader(HttpServletResponse response, String fileName) {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8).replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + encodedFileName + ".xlsx");
    }
}
